Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

249
Vistas
Error "Se esperaba que la operación de la base de datos afectara a 1 fila(s) pero en realidad afectó a 0 fila(s)" al agregar una entidad relacionada

He estado buscando una solución para escribir un método de actualización "genérico" en EF Core que actualice todas las propiedades modificadas de una entidad, incluida una colección relacionada. La razón de esto es que almaceno las traducciones del nombre de una entidad en una tabla diferente. Encontré esta solución que parecía funcionar bien al principio, pero luego me di cuenta de que aparece un error "Se esperaba que la operación de la base de datos afectara a 1 fila (s) pero en realidad afectó a 0 fila (s)" cuando lo único que cambié en el entidad estaba agregando una nueva traducción de nombre en la tabla relacionada TblProjectTranslations . Aquí está mi código:

 public async Task UpdateProjectAsync(TblProject updatedEntity) { TblProject dbEntity = Context.TblProjects .Include(dbEntity => dbEntity.TblProjectTranslations) .SingleOrDefault(dbEntity => dbEntity.ProjectId == updatedEntity.ProjectId); if (dbEntity != null) { Context.Entry(dbEntity).CurrentValues.SetValues(updatedEntity); foreach (TblProjectTranslation dbTranslation in dbEntity.TblProjectTranslations.ToList()) { if (!updatedEntity.TblProjectTranslations .Any(translation => translation.ProjectId == dbTranslation.ProjectId && translation.Language == dbTranslation.Language)) { Context.TblProjectTranslations.Remove(dbTranslation); } } foreach (TblProjectTranslation newTranslation in updatedEntity.TblProjectTranslations) { TblProjectTranslation dbTranslation = dbEntity.TblProjectTranslations .SingleOrDefault(dbTranslation => dbTranslation.ProjectId == newTranslation.ProjectId && dbTranslation.Language == newTranslation.Language); if (dbTranslation != null) { Context.Entry(dbTranslation).CurrentValues.SetValues(newTranslation); } else { dbEntity.TblProjectTranslations.Add(newTranslation); } } await Context.SaveChangesAsync(); } }

Estas son las clases de ingeniería inversa de EF Core:

 public partial class TblProject { public TblProject() { TblProjectTranslations = new HashSet<TblProjectTranslation>(); } public int ProjectId { get; set; } public virtual ICollection<TblProjectTranslation> TblProjectTranslations { get; set; } } public partial class TblProjectTranslation { public int ProjectId { get; set; } public string Language { get; set; } public string ProjectName { get; set; } public virtual TblProject Project { get; set; } }

Así es como se definen en OnModelCreating :

 modelBuilder.Entity<TblProject>(entity => { entity.HasKey(e => e.ProjectId); entity.ToTable("TBL_project"); entity.Property(e => e.ProjectId).HasColumnName("project_ID"); }); modelBuilder.Entity<TblProjectTranslation>(entity => { entity.HasKey(e => new { e.ProjectId, e.Language }); entity.ToTable("TBL_project_translation"); entity.HasIndex(e => e.ProjectId, "IX_TBL_project_translation_project_ID"); entity.Property(e => e.ProjectId).HasColumnName("project_ID"); entity.Property(e => e.Language) .HasMaxLength(5) .HasColumnName("language") .HasDefaultValueSql("('-')"); entity.Property(e => e.ProjectName) .IsRequired() .HasMaxLength(50) .HasColumnName("project_name") .HasDefaultValueSql("('-')"); entity.HasOne(d => d.Project) .WithMany(p => p.TblProjectTranslations) .HasForeignKey(d => d.ProjectId) .OnDelete(DeleteBehavior.ClientSetNull) .HasConstraintName("TBL_project_translation_TBL_project"); });

Lo que no entiendo es que dbEntity.TblProjectTranslations.Add(newTranslation) parece ser el problema. Cuando reemplazo esta línea con await Context.TblProjectTranslations.AddAsync(newTranslation) , el error "mágicamente" desaparece, pero ¿no se supone que ambas formas deben hacer básicamente lo mismo? Aquí hay un ejemplo de una updatedEntity y una dbEntity de base de datos que capturé mientras depuraba la función justo antes de que ocurriera el problema:

 updatedEntity: ProjectId: 41 TblProjectTranslations: 1 Entry with: Language: "en" Project: null ProjectId: 41 ProjectName: "TestNameEN" dbEntity: ProjectId: 41 TblProjectTranslations: No entries

¿Que esta pasando aqui? Ni siquiera tengo ningún activador en la base de datos en ambas tablas que parecían ser la causa de este error para otras personas.

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Después de jugar un poco con el modelo de muestra, el código y las explicaciones, finalmente pude reproducirlo. El culpable parece ser la clave compuesta y el valor predeterminado para la parte de la cadena:

 entity.HasKey(e => new { e.ProjectId, e.Language }); // (1) entity.Property(e => e.Language) .HasMaxLength(5) .HasColumnName("language") .HasDefaultValueSql("('-')"); // (2)

Lo mismo sucede si usas

 .HasDefaultValue("-")

Esta combinación de alguna manera hace que EF considere el elemento agregado a la propiedad de navegación de la colección principal

 dbEntity.TblProjectTranslations.Add(newTranslation);

como Modified en lugar de Added , lo que luego conduce al error en cuestión.

Dado que no puedo encontrar una explicación de dicho comportamiento en la documentación de EF Core y, en general, se ve mal, sugeriría ir e informarlo al rastreador de problemas de EF Core GitHub .

Mientras tanto, las posibles soluciones que veo son

  • Eliminar .HasDefaultValueSql / .HasDefaultValue para la columna de clave

  • En lugar de agregar el elemento secundario a la colección principal, agréguelo directamente al contexto o al DbSet correspondiente (opcionalmente, configure la propiedad de navegación de referencia de antemano "por si acaso"):

 newTranslation.Project = dbEntity; Context.Add(newTranslation);
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda